package com.kk.myapplication;

import android.annotation.SuppressLint;
import android.app.Presentation;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.kk.myapplication.abs.IMainListener;
import com.kk.myapplication.databinding.ActivityMainBinding;
import com.kk.myapplication.databinding.LayoutPresentationSecondBinding;
import com.kk.myapplication.model.MainModel;
import com.kk.myapplication.model.PresentationModel;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements IMainListener {

    private static final String TAG = "MainActivity";

    private ActivityMainBinding mBinding;
    private MainModel mMainModel = new MainModel();

    private MyPresentation mMyPresentation = null;

    private IBinder mMirrorBinder = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
        mMainModel.setListener(this);
        setContentView(mBinding.getRoot());
        mBinding.setModel(mMainModel);

    }


    IBinder getDisplayBinder(int displayId) {
        try {
            @SuppressLint("PrivateApi") Class<?> mClassType = Class.forName("android.view.SurfaceControl");
            Method getBuiltInDisplayMethod = mClassType.getMethod("getBuiltInDisplay", int.class);
            IBinder displayToken = (IBinder) getBuiltInDisplayMethod.invoke(mClassType, displayId);
            return displayToken;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


//    public DisplayInfo getDisplayInfo(int displayId) {
//        try {
//            Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, displayId);
//            if (displayInfo == null) {
//                // fallback when displayInfo is null
//                return getDisplayInfoFromDumpsysDisplay(displayId);
//            }
//            Class<?> cls = displayInfo.getClass();
//            // width and height already take the rotation into account
//            int width = cls.getDeclaredField("logicalWidth").getInt(displayInfo);
//            int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
//            int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
//            int layerStack = cls.getDeclaredField("layerStack").getInt(displayInfo);
//            int flags = cls.getDeclaredField("flags").getInt(displayInfo);
//            return new DisplayInfo(displayId, new Size(width, height), rotation, layerStack, flags);
//        } catch (ReflectiveOperationException e) {
//            throw new AssertionError(e);
//        }
//    }

    private void setUpVirtualDisplay() {
        Log.i(TAG, "createDisplay begin ");


        Display display = getHDMIDisplay();
        if (display == null) {
            Log.e(TAG, "setUpVirtualDisplay: 异显获取失败 " + display);
            return;
        }

        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getRealMetrics(displayMetrics);

        try {
            mMirrorBinder = SurfaceControl.createDisplay("1111", false);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.i(TAG, "setUpVirtualDisplay: " + mMirrorBinder);
        Log.i(TAG, "createDisplay end " + mMirrorBinder);
        SurfaceControl.openTransaction();
        try {
            if (mMirrorBinder != null) {
                SurfaceControl.setDisplaySurface(mMirrorBinder, mBinding.mirrorSurface.getHolder().getSurface());
                Log.i(TAG, "setUpVirtualDisplay: " + mBinding.mirrorSurface.getWidth() + "  " + mBinding.mirrorSurface.getHeight());

                Rect deviceRect = new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
                Rect displayRect = new Rect(0, 0, mBinding.mirrorSurface.getWidth(), mBinding.mirrorSurface.getHeight());
                SurfaceControl.setDisplayProjection(mMirrorBinder, 0, deviceRect, displayRect);
                SurfaceControl.setDisplayLayerStack(mMirrorBinder, 1);
            }
        } finally {
            SurfaceControl.closeTransaction();
        }
    }


    private Display getHDMIDisplay() {
        DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        if (displays != null && displays.length > 0) {
            return displays[0];
        }

        return null;
    }

    @Override
    public void onBtnScanDisplay() {
        DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
        Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);

        Log.i(TAG, "initListener: " + displays.length);

        for (int i = 0; i < displays.length; i++) {

            IBinder iBinder = getDisplayBinder(displays[i].getDisplayId());
            Log.i(TAG, "iBinder: " + iBinder + "  initListener: " + displays[i] + "  displayID:" + displays[i].getDisplayId());
        }
    }

    @Override
    public void onBtnOpenPresentation() {
        showPresentation();
    }

    @Override
    public void onBtnClosePresentation() {
        hidePresentation();
    }

    @Override
    public void onBtnOpenMirror() {

        setUpVirtualDisplay();
    }

    @Override
    public void onBtnCloseMirror() {

        try {
            if (mMirrorBinder != null) {
                SurfaceControl.destroyDisplay(mMirrorBinder);
                mMirrorBinder = null;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void showPresentation() {
        if (mMyPresentation == null) {
            DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
            Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
            if (displays != null && displays.length > 0) {
                mMyPresentation = new MyPresentation(this, displays[0]);
            }
        }
        if (mMyPresentation != null) {
            mMyPresentation.show();
        }
    }

    private void hidePresentation() {
        if (mMyPresentation != null) {
            mMyPresentation.dismiss();
            mMyPresentation = null;
        }
    }


    private final class MyPresentation extends Presentation {

        private PresentationModel mPresentationModel = new PresentationModel();
        private LayoutPresentationSecondBinding mPresentationSecondBinding;
        private Timer mTimer = null;
        private long mCount = 0;
        private String mStartTime = "";
        private long mStartTimeMillis = 0;

        private MyPresentation(Context outerContext, Display display) {
            super(outerContext, display);
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            mPresentationSecondBinding = LayoutPresentationSecondBinding.inflate(getLayoutInflater());
            setContentView(mPresentationSecondBinding.getRoot());
            mPresentationSecondBinding.setModel(mPresentationModel);
            mStartTime = getNowTime();

            mStartTimeMillis = SystemClock.elapsedRealtime();
        }

        private String getNowTime() {
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = sdf.format(date);
            return dateString;
        }

        @Override
        public void show() {
            super.show();

            if (mTimer != null) {
                mTimer.cancel();
                mTimer = null;
            }

            mTimer = new Timer("update");
            mTimer.schedule(new TimerTask() {
                @Override
                public void run() {

                    mCount++;

                    long runTime = (SystemClock.elapsedRealtime() - mStartTimeMillis) / 1000;

                    mPresentationModel.setMessage("开始时间：" + mStartTime + " \n当前时间：" + getNowTime() + "\n运行时间：" + runTime + "秒\n计数：" + mCount);
                }
            }, 0, 1000);
        }

        @Override
        public void dismiss() {
            super.dismiss();
            if (mTimer != null) {
                mTimer.cancel();
                mTimer = null;
            }
        }
    }
}